package com.so.np2.algs;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


// 	Link para estudar! 
//	http://ces33.wikidot.com/gerenciamento-de-memoria:jose-gerardo-e-diego-alvarez#toc10
public class MainFrame extends JFrame implements ActionListener {
	private static final long serialVersionUID = 1L;
	public static final int NUMERO_ALGORITMOS = 8;
	JTextField tfRequests;
	JTextField tfQ1;
	JTextField tfQ2;
	JTextField tfBitR;

	JButton btnReadRequests;
	JButton btnOutputGraphic;
	JButton btnOutputResultTable;

	List<Request> requests;
	List<HitResult> results;

	GraphicResults graphicResults;
	WorkbookImpl excel;

	String btnRequestsName = "requests";
	String btnGraphicName = "graphic";
	String btnTableName = "table";

	boolean requestsLoaded;
	int q1;
	int q2;
	int intervaloBitR;

	public static void main(String[] args) {
		new MainFrame();
	}

	public MainFrame() {
		requestsLoaded = false;
		initComponents();
		setVisible(true);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(608, 235);
		setLocationRelativeTo(null);
		setTitle("Memory Swap Algorithms - Daniel Alves e Allan Ara\u00FAjo - 2011.2");
		init();
	}

	private void init() {
		JFileChooser fc = new JFileChooser();
		fc.removeChoosableFileFilter(fc.getAcceptAllFileFilter());
		fc.addChoosableFileFilter(new FileFilterImpl());
		if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(null)) {
			File f = fc.getSelectedFile();
			tfRequests.setText(f.getAbsolutePath());
			try {
				requests = FileUtil.readRequests(f);
				JOptionPane.showMessageDialog(null, "OK!");
				requestsLoaded = true;
			} catch (NumberFormatException e1) {
				JOptionPane.showMessageDialog(null, "ERROR!");
			}
		}

		btnOutputGraphic.setEnabled(requestsLoaded);
		btnOutputResultTable.setEnabled(requestsLoaded);
	}

	private void initComponents() {
		getContentPane().setLayout(null);

		JLabel lblPathDoArquivo = new JLabel("Requests");
		lblPathDoArquivo.setBounds(10, 60, 164, 16);
		getContentPane().add(lblPathDoArquivo);

		tfRequests = new JTextField();
		tfRequests.setBounds(10, 83, 500, 22);
		getContentPane().add(tfRequests);
		tfRequests.setColumns(10);

		JLabel lblNDeFrames = new JLabel("Q1");
		lblNDeFrames.setBounds(10, 122, 25, 16);
		getContentPane().add(lblNDeFrames);

		tfQ1 = new JTextField();
		tfQ1.setBounds(10, 145, 25, 22);
		getContentPane().add(tfQ1);
		tfQ1.setColumns(10);

		tfQ2 = new JTextField();
		tfQ2.setBounds(47, 145, 29, 22);
		getContentPane().add(tfQ2);
		tfQ2.setColumns(10);

		JLabel lblIntervaloBitR = new JLabel("Bit R");
		lblIntervaloBitR.setBounds(88, 122, 29, 16);
		getContentPane().add(lblIntervaloBitR);

		tfBitR = new JTextField();
		tfBitR.setBounds(88, 145, 29, 22);
		getContentPane().add(tfBitR);
		tfBitR.setColumns(10);

		btnReadRequests = new JButton("Select");
		btnReadRequests.setBounds(513, 84, 84, 25);
		getContentPane().add(btnReadRequests);
		btnReadRequests.addActionListener(this);
		btnReadRequests.setActionCommand(btnRequestsName);

		btnOutputGraphic = new JButton("Graphic");
		btnOutputGraphic.setBounds(10, 180, 164, 25);
		getContentPane().add(btnOutputGraphic);
		btnOutputGraphic.addActionListener(this);
		btnOutputGraphic.setActionCommand(btnGraphicName);
		btnOutputGraphic.setEnabled(requestsLoaded);

		JLabel lblQ = new JLabel("Q2");
		lblQ.setBounds(44, 122, 25, 16);
		getContentPane().add(lblQ);

		btnOutputResultTable = new JButton("Table");
		btnOutputResultTable.setBounds(184, 181, 164, 23);
		getContentPane().add(btnOutputResultTable);
		btnOutputResultTable.addActionListener(this);
		btnOutputResultTable.setActionCommand(btnTableName);
		btnOutputResultTable.setEnabled(requestsLoaded);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals(btnRequestsName)) {
			init();
		} else if (e.getActionCommand().equals(btnGraphicName)) {
			if (!requestsLoaded) {
				return;
			}
			graphic();
		} else if (e.getActionCommand().equals(btnTableName)) {
			if (results == null || results.size() == 0) {
				graphic();
			}
			getFields();
			excel = new WorkbookImpl(results, q1, q2, intervaloBitR);
			excel.getXLS();
			try {
				excel.exportar("C:\\");
			} catch (IOException e1) {
			}
		}
	}

	private void graphic() {
		results = new ArrayList<HitResult>();

		getFields();

		gerarResultados(q1, q2, intervaloBitR);

		graphicResults = new GraphicResults(results, q1, q2);
		graphicResults.chartPanel.setBounds(0, 0, 400, 500);
		Graphic gc = new Graphic();
		gc.contentPane.removeAll();
		gc.contentPane.add(graphicResults.chartPanel);
		gc.setVisible(true);

		repaint();
	}

	private void gerarResultados(int q1, int q2, int intervaloBitR) {
		List<Strategy> algoritmos = new ArrayList<Strategy>();
		algoritmos.add(new FIFO(0, requests));
		algoritmos.add(new Random(0, requests));
		algoritmos.add(new Best(0, requests));
		algoritmos.add(new LFU(0, requests));
		algoritmos.add(new MFU(0, requests));
		algoritmos.add(new SecondChance(0, requests, intervaloBitR));
		algoritmos.add(new MRU(0, requests));
		algoritmos.add(new NUR(0, requests, intervaloBitR));

		for (int i = q1; i <= q2; i++) {
			HitResult resultado = new HitResult();
			resultado.frame = i;
			for (Strategy algorithmModel : algoritmos) {
				algorithmModel.frameSize = i;
				algorithmModel.run();
				resultado.adicionarResultado(algorithmModel.hit,
						algorithmModel.getCanonicalName());
				algorithmModel.reset();
			}
			results.add(resultado);
		}
	}

	private void getFields() {
		q1 = Integer.parseInt(tfQ1.getText());
		q2 = Integer.parseInt(tfQ2.getText());
		intervaloBitR = Integer.parseInt(tfBitR.getText());
	}
}
